package demo25;

public class Test {
    public static void main(String[] args) {

    }


    public static ListNode reverseKGroup(ListNode head, int k) {
        ListNode result;
        ListNode start;//这个是当前链表段的起点
        ListNode start1 = head;//这个是下一个链表段的起点
        ListNode start2;//这个是下下个链表段的起点
        ListNode ahead = null;//这个是每次节点的起点的下一个节点
        ListNode exchange = null;
        boolean isEnd = false;//是否已经翻转结束，循环结束
        boolean needConnect = true;
        //确定结果链表的起点
        for (int i = 0; i < k-1; i++) {
            if(start1 == null){
                result = head;
                return result;
            }
            start1 = start1.next;
        }
        result = start1;
        //给结果链表配置好起点后，初始化start1
        start1 = head;
        while(!isEnd){
            for (int i = 0; i < k; i++) {
                //这层循环负责检查这个链表后续是否还有足够长的内容
                if(start1 == null){
                    isEnd = true;
                    break;
                }
                else{
                    //将链表节点向后推进
                    start1 = start1.next;
                }
            }
            start2 = start1;
            for (int i = 0; i < k-1; i++) {
                //这层循环负责检查这个链表后续是否够2k-1的长度，给当前起点与2k-1后的节点相连
                if(start2 == null){
                    //不需要连接这个2k后的节点，而是连接start1当前指向的位置即可
                    needConnect = false;
                    break;
                }
                else{
                    //将链表节点向后推进
                    start2 = start2.next;
                }
            }
            if(start2 == null){
                needConnect = false;
            }
            if(isEnd){
                //剩下的这个链表段不够长度k，所以不用翻转
                break;
            }
            //如果这条链表足够长，就将当前长度为k的部分进行翻转
            //获取当前起点
            start = head;
            //获取当前需要交换的左节点
            exchange = start;
            //获取起点的下一个节点（右节点）
            ahead = head.next;
            //移动head
            head = head.next;
            for (int i = 0; i < k-1; i++) {
                //循环交换节点的指向，将右节点指向左节点，以此往复
                head = head.next;
                ahead.next = exchange;
                exchange = ahead;
                ahead = head;
            }
            //将每次翻转的起点，指向下一个链表段的终点/起点，其条件取决于下个链表段的长度
            if(needConnect){
                //连接下一段的终点
                start.next = start2;
            }else{
                //连接下一段的起点
                start.next = start1;
            }
        }
        return result;
    }
}


class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}